home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
edit
/
thesrc20.zip
/
box.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-26
|
14KB
|
399 lines
/***********************************************************************/
/* BOX.C - */
/* This file contains all functions relating to box operations. */
/***********************************************************************/
/*
* THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
* Copyright (C) 1991-1995 Mark Hessling
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
*
* The Free Software Foundation, Inc.
* 675 Mass Ave,
* Cambridge, MA 02139 USA.
*
*
* If you make modifications to this software that you feel increases
* it usefulness for the rest of the community, please email the
* changes, enhancements, bug fixes as well as any and all ideas to me.
* This software is going to be maintained and enhanced as deemed
* necessary by the community.
*
* Mark Hessling email: M.Hessling@gu.edu.au
* 36 David Road Phone: +61 7 849 7731
* Holland Park Fax: +61 7 875 5314
* QLD 4121
* Australia
*/
/*
$Id: box.c 2.0 1995/01/26 16:29:44 MH Release MH $
*/
#include <stdio.h>
#include "the.h"
#include "proto.h"
/*#define DEBUG 1*/
/***********************************************************************/
#ifdef PROTO
void box_operations(short action,CHARTYPE reset,bool overlay,CHARTYPE fillchar)
#else
void box_operations(action,reset,overlay,fillchar)
short action;
CHARTYPE reset;
bool overlay;
CHARTYPE fillchar;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern VIEW_DETAILS *vd_mark;
/*--------------------------- local data ------------------------------*/
BOXP boxp;
short rc=RC_OK;
unsigned short y=0,x=0;
LENGTHTYPE offset=0;
short save_mark_type=MARK_VIEW->mark_type;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:box_operations");
#endif
/*---------------------------------------------------------------------*/
/* This procedure is for copying, deleting, filling, moving and */
/* overlaying box blocks. Box blocks consist of BOX, WORD and COLUMN */
/* blocks. */
/*---------------------------------------------------------------------*/
post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
/*---------------------------------------------------------------------*/
/* If the command was issued on the command line then the destination */
/* line is the current line and the destination column is 0; */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
{
if (CURRENT_VIEW->current_line == 0L)
boxp.dst_start_line = 1L;
else
boxp.dst_start_line = CURRENT_VIEW->current_line;
boxp.dst_start_col = 0;
}
else
{
if (CURRENT_VIEW->focus_line == 0L)
boxp.dst_start_line = 1L;
else
boxp.dst_start_line = CURRENT_VIEW->focus_line;
getyx(CURRENT_WINDOW,y,x);
boxp.dst_start_col = x + CURRENT_VIEW->verify_col-1;
}
boxp.src_start_line = MARK_VIEW->mark_start_line;
boxp.src_start_col = MARK_VIEW->mark_start_col-1;
boxp.num_cols = MARK_VIEW->mark_end_col - MARK_VIEW->mark_start_col + 1;
/*---------------------------------------------------------------------*/
/* If the block type is COLUMN, the number of lines to operate on is */
/* the number of lines in the source file and the destination start */
/* line is line 1. Reset these values set above. */
/*---------------------------------------------------------------------*/
if (MARK_VIEW->mark_type == M_COLUMN)
{
boxp.num_lines = MARK_VIEW->file_for_view->number_lines - boxp.src_start_line +1L;
boxp.dst_start_line = 1L;
}
else
boxp.num_lines = MARK_VIEW->mark_end_line - boxp.src_start_line +1L;
/*---------------------------------------------------------------------*/
/* Find the current LINE pointer for both the source and destination */
/* lines. */
/*---------------------------------------------------------------------*/
boxp.curr_src = lll_find(MARK_FILE->first_line,boxp.src_start_line);
if (action != BOX_D)
boxp.curr_dst = lll_find(CURRENT_FILE->first_line,boxp.dst_start_line);
/*---------------------------------------------------------------------*/
/* Call the appropriate box function... */
/*---------------------------------------------------------------------*/
boxp.action = action;
switch(action)
{
case BOX_D:
rc = box_delete(&boxp);
break;
case BOX_M:
rc = box_move(&boxp,overlay);
break;
case BOX_C:
/* rc = box_copy(&boxp,overlay);*/
rc = box_move(&boxp,overlay);
break;
case BOX_F:
rc = box_fill(&boxp,fillchar);
break;
}
if ((rc = increment_alt(CURRENT_FILE)) != RC_OK)
{
#ifdef TRACE
trace_return();
#endif
return; /* should return a value */
}
/*---------------------------------------------------------------------*/
/* Set the parameters in the MARK_VIEW to OFF; */
/*---------------------------------------------------------------------*/
MARK_VIEW->marked_line = MARK_VIEW->marked_col = FALSE;
MARK_VIEW = (VIEW_DETAILS *)NULL;
/*---------------------------------------------------------------------*/
/* If we are not resetting the block, set up block markers... */
/*---------------------------------------------------------------------*/
if (reset != SOURCE_BLOCK_RESET)
{
if (boxp.src_start_col < boxp.dst_start_col
&& action == BOX_M)
offset = boxp.num_cols;
MARK_VIEW = CURRENT_VIEW;
MARK_VIEW->mark_start_line = boxp.dst_start_line;
MARK_VIEW->mark_end_line = boxp.dst_start_line+boxp.num_lines-1L;
MARK_VIEW->mark_start_col = boxp.dst_start_col+1-offset;
MARK_VIEW->mark_end_col = boxp.dst_start_col+boxp.num_cols-offset;
MARK_VIEW->mark_type = save_mark_type;
MARK_VIEW->marked_line = MARK_VIEW->marked_col = TRUE;
wmove(CURRENT_WINDOW,y,x-offset);
}
pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
build_current_screen();
display_current_screen(); /* should only call this is the marked block is in view */
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef PROTO
short box_delete(BOXP *prm)
#else
short box_delete(prm)
BOXP *prm;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern VIEW_DETAILS *vd_mark;
/*--------------------------- local data ------------------------------*/
LINETYPE i=0L;
LENGTHTYPE j=0;
short num_to_move=0;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:box_delete");
#endif
for (i=0L;i<prm->num_lines;i++)
{
num_to_move = prm->curr_src->length - MARK_VIEW->mark_end_col;
if (num_to_move < 0)
num_to_move = 0;
add_to_recovery_list(prm->curr_src->line,prm->curr_src->length);
prm->curr_src->length = min(prm->curr_src->length,prm->src_start_col+num_to_move);
for (j=0;j<num_to_move;j++)
*(prm->curr_src->line+j+prm->src_start_col) = *(prm->curr_src->line+prm->src_start_col+j+prm->num_cols);
*(prm->curr_src->line+prm->curr_src->length) = '\0';/* null terminate */
prm->curr_src = prm->curr_src->next; /* this should NEVER go past the end */
}
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
short box_move(BOXP *prm,bool overlay)
#else
short box_move(prm,overlay)
BOXP *prm;
bool overlay;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern CHARTYPE *rec;
extern unsigned short rec_len;
/*--------------------------- local data ------------------------------*/
LINETYPE i=0L;
LINE *first_save=NULL,*save_src=NULL,*tmp=NULL;
bool copy_first=FALSE;
LINETYPE save_src_start_line=0L;
LENGTHTYPE save_src_start_col=0;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:box_move");
#endif
if (prm->dst_start_col > prm->src_start_col+prm->num_cols)
copy_first = TRUE;
save_src_start_col = prm->src_start_col;
save_src_start_line = prm->src_start_line;
if (copy_first)
{
save_src = prm->curr_src;
box_copy(prm,overlay);
prm->src_start_line = save_src_start_line;
prm->src_start_col = save_src_start_col;
prm->curr_src = save_src;
if (prm->action == BOX_M)
box_delete(prm);
}
else
{
/*---------------------------------------------------------------------*/
/* Save the data that is to be deleted. It is saved in a format that */
/* can be used in copy_box() as the src line pointer. */
/*---------------------------------------------------------------------*/
tmp = prm->curr_src;
for (i=0L;i<prm->num_lines;i++)
{
memset(rec,' ',max_line_length); /* copy line into rec[] */
memcpy(rec,tmp->line,tmp->length);
rec_len = tmp->length;
if ((save_src = add_line(first_save,save_src,
rec+prm->src_start_col,prm->num_cols,0)) == (LINE *)NULL)
{
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
if (first_save == (LINE *)NULL)
first_save = save_src;
tmp = tmp->next;
}
if (prm->action == BOX_M)
box_delete(prm);
prm->src_start_line = 0L;
prm->src_start_col = 0;
prm->curr_src = first_save;
box_copy(prm,overlay);
first_save = lll_free(first_save);
prm->src_start_line = save_src_start_line;
prm->src_start_col = save_src_start_col;
}
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
short box_copy(BOXP *prm,bool overlay)
#else
short box_copy(prm,overlay)
BOXP *prm;
bool overlay;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern CHARTYPE *rec;
extern unsigned short rec_len;
/*--------------------------- local data ------------------------------*/
LINETYPE i=0L;
LENGTHTYPE j=0;
CHARTYPE chr=0;
short rc=RC_OK;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:box_copy");
#endif
for (i=0L;i<prm->num_lines;i++)
{
if (prm->curr_dst->next == (LINE *)NULL) /* on *** Bottom of File *** */
{
if ((prm->curr_dst = add_line(CURRENT_FILE->first_line,prm->curr_dst->prev,
(CHARTYPE *)"",0,0)) == (LINE *)NULL)
{
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
CURRENT_FILE->number_lines++;
}
pre_process_line(CURRENT_VIEW,prm->dst_start_line+i);/* copy dest line into rec */
for (j=0;j<prm->num_cols;j++)
{
if (prm->src_start_col+j+1 > prm->curr_src->length)
chr = (CHARTYPE)' ';
else
chr = (CHARTYPE)*(prm->curr_src->line+prm->src_start_col+j);
if (overlay)
rec[prm->dst_start_col+j] = chr;
else
meminschr(rec,chr,prm->dst_start_col+j,max_line_length,rec_len++);
}
rc = memrevne(rec,' ',max_line_length);
if (rc == (-1))
rec_len = 0;
else
rec_len = rc+1;
post_process_line(CURRENT_VIEW,prm->dst_start_line+i);
prm->curr_src = prm->curr_src->next; /* this should NEVER go past the end */
prm->curr_dst = prm->curr_dst->next; /* this should NEVER go past the end */
}
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
short box_fill(BOXP *prm,CHARTYPE fillchar)
#else
short box_fill(prm,fillchar)
BOXP *prm;
CHARTYPE fillchar;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern CHARTYPE *rec;
extern unsigned short rec_len;
/*--------------------------- local data ------------------------------*/
LINETYPE i=0L;
LENGTHTYPE j=0;
short rc=RC_OK;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:box_fill");
#endif
for (i=0L;i<prm->num_lines;i++)
{
pre_process_line(CURRENT_VIEW,prm->src_start_line+i);/* copy source line into rec */
for (j=0;j<prm->num_cols;j++)
rec[prm->src_start_col+j] = fillchar;
rc = memrevne(rec,' ',max_line_length);
if (rc == (-1))
rec_len = 0;
else
rec_len = rc+1;
post_process_line(CURRENT_VIEW,prm->src_start_line+i);
prm->curr_src = prm->curr_src->next; /* this should NEVER go past the end */
}
prm->dst_start_col = prm->src_start_col;
prm->dst_start_line = prm->src_start_line;
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}